import sys
from typing import Dict, Any, Callable, Optional
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QMenu, QFrame, QSizePolicy
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon, QKeySequence, QAction

from .factory import WidgetFactory
from .config import ConfigManager
from .models import AppConfig, MenuConfig, ToolbarConfig, DockWidgetConfig, ButtonConfig
from .styles import StyleManager

class MainWindow(QMainWindow):
    """主窗口类"""
    def __init__(self, config: Optional[AppConfig] = None):
        super().__init__()
        
        # 设置窗口基本属性
        self.config = config or AppConfig()
        self.setWindowTitle(self.config.title)
        self.setGeometry(
            self.config.window_position[0], 
            self.config.window_position[1],
            self.config.window_size[0], 
            self.config.window_size[1]
        )
        
        # 修改DockWidget的默认区域布局
        self.setDockNestingEnabled(True)  # 启用DockWidget嵌套
        
        # 禁用顶部DockWidget区域，只允许左侧、右侧和底部
        self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks)
        self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea)
        self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea)
        
        # 创建顶部容器用于放置Tab部件
        top_container = QWidget()
        top_container.setObjectName("TopContainer")
        top_layout = QVBoxLayout(top_container)
        top_layout.setContentsMargins(0, 0, 0, 0)
        top_layout.setSpacing(0)
        
        # 设置顶部容器的尺寸策略为固定高度，使其表现为2的部分
        top_container.setFixedHeight(120) # 固定高度
        top_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        
        # 创建Tab部件，放在顶部容器中
        self.tab_widget = WidgetFactory.create_tabwidget()
        top_layout.addWidget(self.tab_widget)
        
        # 连接TabWidget的折叠信号到槽函数
        self.tab_widget.collapseStateChanged.connect(self.on_tab_widget_collapse)
        
        # 创建主容器
        main_container = QWidget()
        main_container.setObjectName("MainContainer")
        main_layout = QVBoxLayout(main_container)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        
        # 设置主容器的尺寸策略为扩展，使其表现为8的部分
        main_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        
        # 添加一个空的占位部件，作为内容区域
        self.placeholder = QWidget()
        self.placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        main_layout.addWidget(self.placeholder)
        
        # 将顶部容器设置为MenuWidget
        self.setMenuWidget(top_container)
        self.top_container = top_container  # 保存引用以便后续调整
        
        # 将主容器设置为CentralWidget
        self.setCentralWidget(main_container)
        
        # 初始化数据
        self.dock_widgets = []
        self.callback_map = {}
        
    def register_callbacks(self, callbacks: Dict[str, Callable]):
        """注册回调函数"""
        self.callback_map.update(callbacks)
        
    def get_callback(self, name: str) -> Optional[Callable]:
        """根据名称获取回调函数"""
        return self.callback_map.get(name)
        
    def init_tab_menu(self, menu_configs: Optional[list] = None):
        """初始化标签菜单，取代传统菜单栏"""
        # 使用配置文件中的菜单配置或使用默认配置
        configs = menu_configs or self.config.menus
        
        # 为每个主菜单创建标签页
        for menu_config in configs:
            # 为每个工具栏创建一个工具栏容器
            for toolbar_config in menu_config.toolbars:
                # 创建工具栏
                toolbar = self.tab_widget.addToolbar(menu_config.title, toolbar_config.barname)
                
                # 为每个按钮项添加按钮
                for item in toolbar_config.items:
                    # 如果有子菜单，处理子菜单项
                    if item.submenu:
                        # 为子菜单创建下拉按钮或其他适当的UI组件
                        # 这里可以根据需要扩展功能
                        pass
                    else:
                        # 创建工具按钮
                        button = WidgetFactory.create_toolbutton(item.text, item.icon)
                        
                        # 连接回调函数
                        callback = self.get_callback(item.callback_name) if item.callback_name else None
                        if callback:
                            button.clicked.connect(callback)
                            
                        # 添加到工具栏
                        toolbar.addWidget(button)
                    
    def add_dock_widget(self, config: DockWidgetConfig):
        """添加停靠窗口"""
        # 创建内容部件
        if config.widget_type:
            widget = WidgetFactory.create_content_widget(
                config.widget_type, 
                self, 
                **config.widget_config
            )
        else:
            widget = QWidget()
            layout = QVBoxLayout(widget)
            layout.addWidget(QLabel(config.title))
        
        # 设置内容部件的最小宽度
        widget.setMinimumWidth(250)  # 增加最小宽度
        
        # 创建停靠窗口
        dock = WidgetFactory.create_dockwidget(config.title, widget, self)
        
        # 设置停靠区域，只允许左侧、右侧和底部
        area_map = {
            "left": Qt.LeftDockWidgetArea,
            "right": Qt.RightDockWidgetArea,
            "bottom": Qt.BottomDockWidgetArea,
            "top": Qt.BottomDockWidgetArea  # 如果配置为top，强制改为bottom
        }
        dock_area = area_map.get(config.area.lower(), Qt.LeftDockWidgetArea)
        dock.setDockArea(dock_area)
        self.addDockWidget(dock_area, dock)
        
        # 设置停靠窗口的大小
        dock.setMinimumWidth(250)  # 设置最小宽度
        if config.area.lower() == "left" or config.area.lower() == "right":
            self.resizeDocks([dock], [300], Qt.Horizontal)  # 设置初始宽度为300
        elif config.area.lower() == "bottom":
            self.resizeDocks([dock], [200], Qt.Vertical)  # 设置初始高度为200
        
        # 设置是否可关闭
        if not config.closable:
            dock.setFeatures(dock.features() & ~dock.DockWidgetClosable)
            
        # 设置是否浮动
        if config.floating:
            dock.setFloating(True)
            
        self.dock_widgets.append(dock)
        return dock

    def on_tab_widget_collapse(self, is_collapsed):
        """响应TabWidget的折叠状态变化"""
        if is_collapsed:
            # TabWidget已折叠，只显示标签栏，内容区域扩展填满
            self.top_container.setMaximumHeight(self.tab_widget.height())
            self.top_container.setMinimumHeight(self.tab_widget.height())
        else:
            # TabWidget已展开，恢复原始高度
            self.top_container.setMaximumHeight(120)
            self.top_container.setMinimumHeight(120)
        
        # 更新布局
        self.update()

class Application:
    """应用程序类，负责初始化整个应用程序"""
    def __init__(self, config_dir: str = "config"):
        # 初始化应用程序和配置
        self.app = QApplication(sys.argv)
        self.config_manager = ConfigManager(config_dir)
        
        # 应用全局样式表
        self.apply_style("light_blue")  # 默认使用淡蓝色主题
        
        # 加载配置，如果不存在则创建默认配置
        try:
            self.config = self.config_manager.load_app_config()
            if not self.config.menus:  # 如果没有菜单配置，可能是新配置文件
                self.config = self.config_manager.create_default_config()
        except Exception as e:
            print(f"加载配置失败，使用默认配置: {str(e)}")
            self.config = self.config_manager.create_default_config()
            
        # 创建主窗口
        self.main_window = MainWindow(self.config)
        
        # 注册回调函数
        self._register_callbacks()
        
    def apply_style(self, style_name: str):
        """应用指定的样式表"""
        if style_name == "light_blue":
            style_sheet = StyleManager.get_light_blue_style()
        elif style_name == "warm_beige":
            style_sheet = StyleManager.get_warm_beige_style()
        else:
            style_sheet = StyleManager.get_light_blue_style()  # 默认样式
            
        self.app.setStyleSheet(style_sheet)
        self.current_style = style_name
        
    def toggle_style(self):
        """切换样式表，在两套样式之间切换"""
        if hasattr(self, 'current_style') and self.current_style == "light_blue":
            self.apply_style("warm_beige")
        else:
            self.apply_style("light_blue")
            
        return self.current_style
        
    def _register_callbacks(self):
        """注册回调函数"""
        callbacks = {
            # 文件菜单
            "new_file": self.new_file,
            "open_file": self.open_file,
            "save_file": self.save_file,
            "exit": self.exit,
            
            # 数据库操作
            "connect_db": self.connect_db,
            "disconnect_db": self.disconnect_db,
            
            # 编辑菜单
            "copy": self.copy,
            "paste": self.paste,
            
            # 视图菜单
            "toggle_toolbar": self.toggle_toolbar,
            "toggle_statusbar": self.toggle_statusbar,
            "toggle_style": self.toggle_style,
            
            # 帮助菜单
            "show_about": self.show_about
        }
        self.main_window.register_callbacks(callbacks)
        
    def init_ui(self):
        """初始化UI"""
        # 初始化标签菜单
        self.main_window.init_tab_menu()
        
        # 初始化停靠窗口
        for dock_config in self.config.dock_widgets:
            self.main_window.add_dock_widget(dock_config)
        
        return self.main_window
    
    # 回调函数
    def new_file(self):
        """新建文件"""
        print("新建文件")
        
    def open_file(self):
        """打开文件"""
        print("打开文件")
        
    def save_file(self):
        """保存文件"""
        print("保存文件")
        
    def exit(self):
        """退出应用程序"""
        self.app.quit()
        
    def copy(self):
        """复制"""
        print("复制")
        
    def paste(self):
        """粘贴"""
        print("粘贴")
        
    def toggle_toolbar(self):
        """切换工具栏显示状态"""
        print("切换工具栏显示状态")
            
    def toggle_statusbar(self):
        """切换状态栏显示状态"""
        statusbar = self.main_window.statusBar()
        statusbar.setVisible(not statusbar.isVisible())
        
    def show_about(self):
        """显示关于对话框"""
        print(f"关于 {self.config.title} v{self.config.version}")
    
    # 数据库相关回调函数
    def connect_db(self):
        """连接数据库"""
        print("连接数据库")
        
    def disconnect_db(self):
        """断开数据库连接"""
        print("断开数据库连接")
    
    def run(self):
        """运行应用程序"""
        self.init_ui()
        self.main_window.show()
        return self.app.exec() 